package ocr

import (
	"C"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"sort"
	"syscall"
	"unsafe"
)

// 获取字符串的长度指针
func lenPtr(s string) uintptr {
	return uintptr(len(s))
}

// 获取数字的指针
func intPtr(n int) uintptr {
	return uintptr(n)
}

// 获取字符串的指针
func strPtr(s string) uintptr {
	return uintptr(unsafe.Pointer(syscall.StringBytePtr(s)))
}

func getCurrentAbPathBywd() string {
	dir, err := os.Getwd()
	if err != nil {
		fmt.Println(err)
	}
	return dir
}

type Row struct {
	Yb   int //
	Yn   int
	Xb   int
	Text map[int]string
}

type Point struct {
	X int
	Y int
}
type Result struct {
	BoxPoints []Point
	Score     float64
	Text      string
}

func toBase64(b []byte) string {
	return base64.StdEncoding.EncodeToString(b)
}
func main() {
	path := "C:\\Users\\fayak\\GolandProjects\\ocr\\image\\1742198881271.png"
	file, err := os.ReadFile(path)
	if err != nil {
		fmt.Println(err)
		return
	}
	var base64Encoding string
	// mimeType := http.DetectContentType(file)
	// // 根据MIME 类型添加适当的 URI 方案头
	// switch mimeType {
	// case "image/jpeg":
	// 	base64Encoding += "data:image/jpeg;base64,"
	// case "image/png":
	// 	base64Encoding += "data:image/png;base64,"
	// }
	// 添加 base64 编码的输出
	base64Encoding = toBase64(file)
	// 打印图片的完整 base64 表示
	Orc(base64Encoding)
	return
	dll, err := syscall.LoadDLL("PaddleOCR.dll")
	if err != nil {
		fmt.Println(err)
		return
	}
	Initjson, _ := dll.FindProc("Initializejson")
	detect, _ := dll.FindProc("Detect")
	enableANSI, _ := dll.FindProc("EnableANSIResult")
	enableJson, _ := dll.FindProc("EnableJsonResult")
	root := getCurrentAbPathBywd()
	Initjson.Call(strPtr(root+"\\inference\\ch_PP-OCRv4_det_infer"),
		strPtr(root+"\\inference\\ch_ppocr_mobile_v2.0_cls_infer"),
		strPtr(root+"\\inference\\ch_PP-OCRv4_rec_infer"),
		strPtr(root+"\\inference\\ppocr_keys.txt"), strPtr("{}"))
	
	// 启用单字节编码返回json串（默认为Unicode，有空格，go不能显示全）
	enableANSI.Call(1) // 0，unicode编码，1，ANSI编码
	enableJson.Call(1) // 0，返回纯字符串结果，1，返回json字符串结果
	
	files, err := ioutil.ReadDir(root + "\\image")
	if err != nil {
		fmt.Println(err)
	}
	
	for _, file := range files {
		res, _, _ := detect.Call(strPtr(root + "\\image\\" + file.Name()))
		p_result := (*C.char)(unsafe.Pointer(res))
		ocrresult := C.GoString(p_result)
		Results := []Result{}
		json.Unmarshal([]byte(ocrresult), &Results)
		
		rows := []Row{}
		// gorData := map[string]func([]Result) ([]Row, int, int){"浙江兆奕科技有限公司": zyData}
		// gor := map[string]func([]Row, int, int) map[int][]string{"浙江兆奕科技有限公司": zyResult}
		var method func([]Row, int, int) map[int][]string
		var resultMethod func([]Result) ([]Row, int, int)
		for _, result := range Results {
			fmt.Println(result.Text)
			// if result.Text == "浙江兆奕科技有限公司" {
			// 	resultMethod = gorData[result.Text]
			// 	method = gor[result.Text]
			// 	break
			// }
		}
		rows, beginRow, yn := resultMethod(Results)
		m := method(rows, beginRow, yn)
		fmt.Println(m)
	}
}

func Orc(date string) []string {
	dll, err := syscall.LoadDLL("PaddleOCR.dll")
	if err != nil {
		fmt.Println(err)
		return nil
	}
	Initjson, _ := dll.FindProc("Initializejson")
	detect, _ := dll.FindProc("DetectBase64")
	enableANSI, _ := dll.FindProc("EnableANSIResult")
	enableJson, _ := dll.FindProc("EnableJsonResult")
	root := getCurrentAbPathBywd()
	Initjson.Call(strPtr(root+"\\inference\\ch_PP-OCRv4_det_infer"),
		strPtr(root+"\\inference\\ch_ppocr_mobile_v2.0_cls_infer"),
		strPtr(root+"\\inference\\ch_PP-OCRv4_rec_infer"),
		strPtr(root+"\\inference\\ppocr_keys.txt"), strPtr("{}"))
	
	// 启用单字节编码返回json串（默认为Unicode，有空格，go不能显示全）
	enableANSI.Call(1) // 0，unicode编码，1，ANSI编码
	enableJson.Call(1) // 0，返回纯字符串结果，1，返回json字符串结果
	
	// detect.Call()
	res, _, _ := detect.Call(strPtr(date))
	// res, _, _ := detect.Call(date...)
	p_result := (*C.char)(unsafe.Pointer(res))
	ocrresult := C.GoString(p_result)
	Results := []Result{}
	json.Unmarshal([]byte(ocrresult), &Results)
	
	// rows := []Row{}
	// gorData := map[string]func([]Result) ([]Row, int, int){"浙江兆奕科技有限公司": zyData}
	// gor := map[string]func([]Row, int, int) map[int][]string{"浙江兆奕科技有限公司": zyResult}
	// var method func([]Row, int, int) map[int][]string
	// var resultMethod func([]Result) ([]Row, int, int)
	for _, result := range Results {
		fmt.Println(result.Text)
	}
	// rows, beginRow, yn := resultMethod(Results)
	// m := method(rows, beginRow, yn)
	return nil
}

func zyResult(rows []Row, beginRow int, yn int) map[int][]string {
	ii := 20000
	endList := [][]int{}
	for _, i2 := range rows[beginRow:] {
		if ii > len(i2.Text) {
			ii = len(i2.Text)
		}
	}
	for _, i2 := range rows[beginRow:] {
		if len(i2.Text) == ii {
			ys := []int{}
			for y, _ := range i2.Text {
				ys = append(ys, y)
			}
			sort.Ints(ys)
			for _, y := range ys {
				n := (y-yn-(i2.Xb-i2.Yn))*2 + (i2.Xb - i2.Yn)
				endList = append(endList, []int{yn, yn + n + 5})
				yn += n
			}
			break
		}
	}
	resultData := map[int][]string{}
	baseString := []string{}
	for i := 0; i < ii; i++ {
		baseString = append(baseString, "")
	}
	for _, i2 := range rows[beginRow:] {
		text := []string{}
		kk := []int{}
		for k, _ := range i2.Text {
			kk = append(kk, k)
		}
		sort.Ints(kk)
		if len(i2.Text) == ii {
			for _, i3 := range kk {
				text = append(text, i2.Text[i3])
			}
			resultData[i2.Yb] = text
			continue
		}
		for _, key := range kk {
			for i, ints := range endList {
				if key > ints[0] && key < ints[1] {
					if _, ok := resultData[i2.Yb]; !ok {
						baseString2 := []string{}
						marshal, _ := json.Marshal(baseString)
						json.Unmarshal(marshal, &baseString2)
						baseString2[0] = i2.Text[key]
						resultData[i2.Yb] = baseString2
					} else {
						resultData[i2.Yb][i] += i2.Text[key]
					}
					break
				}
			}
		}
	}
	return resultData
}

func zyData(Results []Result) ([]Row, int, int) {
	
	begin := false
	beginRow := 0
	rows := []Row{}
	fd := 10
	yn := 0
	for _, result := range Results {
		if len(result.Text) > 0 {
			if result.Text == "收到订单后请务必盖章回传" {
				break
			}
			if len(rows) == 0 {
				rows = []Row{{
					result.BoxPoints[0].Y,
					result.BoxPoints[3].Y,
					result.BoxPoints[1].X,
					map[int]string{0: result.Text},
				}}
			} else {
				ty := true
				for i2, row := range rows {
					if begin {
						if i2 < beginRow {
							continue
						}
						if row.Yb == result.BoxPoints[0].X ||
							(row.Yb+fd >= result.BoxPoints[0].X && result.BoxPoints[0].X >= row.Yb-fd) {
							rows[i2].Text[result.BoxPoints[2].Y] = result.Text
							ty = false
							break
						}
					} else {
						if row.Yb == result.BoxPoints[0].Y ||
							(row.Yb+fd >= result.BoxPoints[0].Y && result.BoxPoints[0].Y >= row.Yb-fd) {
							rows[i2].Text[0] += result.Text
							ty = false
							break
						}
					}
				}
				if ty {
					if begin {
						rows = append(rows, Row{
							result.BoxPoints[0].X,
							result.BoxPoints[1].Y,
							result.BoxPoints[2].Y,
							map[int]string{result.BoxPoints[2].Y: result.Text}})
					} else {
						rows = append(rows, Row{
							result.BoxPoints[0].Y,
							result.BoxPoints[2].Y,
							result.BoxPoints[1].X,
							map[int]string{0: result.Text}})
					}
				}
			}
			if result.Text == "到货日期" {
				beginRow = len(rows)
				yn = result.BoxPoints[2].Y
				begin = true
			}
		}
	}
	return rows, beginRow, yn
}
